#include "out_compilateur.h"


void init_mnemo(string *mnemo){
	mnemo[DAT]="DAT";
	mnemo[MOV]="MOV";
	mnemo[ADD]="ADD";
	mnemo[SUB]="SUB";
	mnemo[JMP]="JMP";
	mnemo[JMZ]="JMZ";
	mnemo[JMG]="JMG";
	mnemo[DJZ]="DJZ";
	mnemo[CMP]="CMP";
}

char findAdr(char **chp){	//find the adressing method
	char *pt=*chp;

	while(*pt==' ') pt++;	//delete the spaces
	if(*pt=='#'){
		pt++;
		*chp=pt;//save the new adress (incremented)
		return 0;
	}else if(*pt=='@'){
		pt++;
		*chp=pt;
		return 2;
	}else{
		return 1;
	}
}


short findArg(char **chp){ //find the argument
	char *pt=*chp;

	while(*pt==' ') pt++;	//delete the spaces
	char s_argA[5]="";
	int ind=0;
	do{
		s_argA[ind]=*pt;
		pt++;
		ind++;
	}while(*pt!=' ' && ind<5);	//while there is no obstacle, we save the char

	short i_argA=atoi(s_argA);	//converion of the argument into int

	*chp=pt;
	return i_argA;
}


void loadFile(Memoire &mem, int entree_mem, char *name){	//load a file in the virtual memory

	char bufferLine[20]="";
	char *ptBufLine=bufferLine;

	ifstream fsource;
	
	fsource.open(name);

	if(!fsource.is_open()){
		fprintf(stderr, "Erreur de chargement du fichier source\n");
		exit(EXIT_FAILURE);
	}

	//file opened successfully

	string mnemo[NB_MNEMO];
	init_mnemo(mnemo);

	int pos_mem=entree_mem;	//position in the memory
	bool instrOk=false;

	while(fsource.getline(bufferLine, 20) > 0){	//for each line in the file
		//printf("lecture : %s\n", bufferLine);
		for(int i=0; i<NB_MNEMO; i++){	//look for a mnemonique
			if(strncmp(bufferLine, mnemo[i].c_str(), 3)==0){	//If the two strings are equals, this is a known instruction
				instrOk=true;
				//printf("reconnu : %s\n", bufferLine);
				mem[pos_mem].setOp(i);	//save the operation
				ptBufLine=strchr(bufferLine, ' '); //delete everything until the first space (included). This means that we delete the operation

				switch(i){
					//only one argument:
					case DAT:
						mem[pos_mem].setAdrA(0);	//adressing method of the argument
					case JMP:
						//adressing method of the argument
						mem[pos_mem].setAdrA(findAdr(&ptBufLine));
						//find the first argument: ArgA
						mem[pos_mem].setArgA(findArg(&ptBufLine));

						mem[pos_mem].printInstr();
						break;

					//2 arguments :
					case MOV:
					case ADD:
					case SUB:
					case JMZ:
					case JMG:
					case DJZ:
					case CMP:
						mem[pos_mem].setAdrA(findAdr(&ptBufLine));
						mem[pos_mem].setArgA(findArg(&ptBufLine));
						mem[pos_mem].setAdrB(findAdr(&ptBufLine));
						mem[pos_mem].setArgB(findArg(&ptBufLine));

						mem[pos_mem].printInstr();
						break;//exit the switch
				}
				break;	//exit the for
			}//end of the if
		}//end of the for
		if(!instrOk){	//no mnemonique found
			fsource.close();
			mem.raz(entree_mem, pos_mem+1);	//reset the memory
			fprintf(stderr, "Erreur de syntaxe dans le fichier source...");
			exit(EXIT_FAILURE);
		}else
			pos_mem++;
	}//end of the while


	fsource.close();

}


